<!DOCTYPE html>
<html>
<head>
	<!-- Global site tag (gtag.js) - Google Analytics -->
	<script async src="https://www.googletagmanager.com/gtag/js?id='UA-133422980-2"></script>
	<script>
	  window.dataLayer = window.dataLayer || [];
	  function gtag(){dataLayer.push(arguments);}
	  gtag('js', new Date());

	  gtag('config', 'UA-133422980-2');
	</script>

	<meta charset="utf-8">
	<meta http-equiv="x-ua-compatible" content="ie=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1">

	<title>
		gem5: Creating a simple configuration script 
	</title>

	<!-- SITE FAVICON -->
	<link rel="shortcut icon" type="image/gif" href="/assets/img/gem5ColorVert.gif"/>

	<link rel="canonical" href="http://localhost:4000/documentation/learning_gem5/part1/simple_config/">
	<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,700,800,600' rel='stylesheet' type='text/css'>
	<link href='https://fonts.googleapis.com/css?family=Muli:400,300' rel='stylesheet' type='text/css'>

	<!-- FAVICON -->
	<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

	<!-- BOOTSTRAP -->
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

	<!-- CUSTOM CSS -->
	<link rel="stylesheet" href="/css/main.css">
</head>


<body>
	<nav class="navbar navbar-expand-md navbar-light bg-light">
  <a class="navbar-brand" href="/">
		<img src="/assets/img/gem5ColorLong.gif" alt="gem5" height=55px>
	</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarNavDropdown">
    <!-- LIST FOR NAVBAR -->
    <ul class="navbar-nav ml-auto">
      <!-- HOME -->
      <li class="nav-item ">
        <a class="nav-link" href="/">Home</a>
      </li>

      <!-- ABOUT -->
			<li class="nav-item dropdown ">
				<a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
					About
				</a>
				<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
          <a class="dropdown-item" href="/about">About gem5</a>
          <a class="dropdown-item" href="/publications">Publications</a>
          <a class="dropdown-item" href="/governance">Governance</a>
				</div>
			</li>

      <!-- DOCUMENTATION -->
			<li class="nav-item dropdown active">
				<a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
					Documentation
				</a>
				<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
					<!-- Pull navigation from _data/documentation.yml -->
					
            <a class="dropdown-item" href="/documentation">gem5 documentation</a>
					
            <a class="dropdown-item" href="/documentation/learning_gem5/introduction">Learning gem5</a>
					
            <a class="dropdown-item" href="http://doxygen.gem5.org/release/current/index.html">gem5 Doxygen</a>
					
            <a class="dropdown-item" href="/documentation/reporting_problems">Reporting Problems</a>
					
				</div>
			</li>

      <!-- EVENTS -->
			<li class="nav-item dropdown ">
        <a class="nav-link" href="/events/">Events</a>
			</li>

      <!-- CONTRIBUTING -->
      <li class="nav-item ">
        <a class="nav-link" href="/contributing">Contributing</a>
      </li>

      <!-- BLOG -->
      <li class="nav-item ">
        <a class="nav-link" href="/blog">Blog</a>
      </li>

      <!-- SEARCH -->
			<li class="nav-item ">
        <a class="nav-link" href="/search">Search</a>
      </li>
    </ul>
  </div>
</nav>

	<main>
		<div class="sidenav-top">
  <div class="sidenav-brand bg-light">
    <a href="/"><img src="/assets/img/gem5ColorLong.gif" height="55px"></a>
  </div>
  <div class="search">
    <form action="/search" method="get">
      <!-- <label for="search-box"><i class="fa fa-search"></i></label> -->
      <input type="text" name="query">
      <button type="submit" name="submit"><i class="fa fa-search"></i></button>
    </form>
  </div>
</div>
<div class="sidenav">
  <!-- Pull navigation from _data/documentation.yml -->
  
    
  
    
    
      <a class="item" href="/documentation/learning_gem5/introduction" role="button" aria-expanded="false" aria-controls="collapseExample">
        Introduction
      </a>
      <div class="collapse " id="introduction">
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#part1" role="button" aria-expanded="false" aria-controls="collapseExample">
        Getting Started
      </a>
      <div class="collapse show" id="part1">
        
          <a class="subitem " href="/documentation/learning_gem5/part1/building">Building gem5</a>
        
          <a class="subitem active" href="/documentation/learning_gem5/part1/simple_config">Creating a simple configuration script</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part1/cache_config">Adding cache to configuration script</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part1/gem5_stats">Understanding gem5 statistics and output</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part1/example_configs">Using the default configuration scripts</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#part2" role="button" aria-expanded="false" aria-controls="collapseExample">
        Modifying/Extending
      </a>
      <div class="collapse " id="part2">
        
          <a class="subitem " href="/documentation/learning_gem5/part2/environment">Setting up your development environment</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/helloobject">Creating a very simple SimObject</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/debugging">Debugging gem5</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/events">Event-driven programming</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/parameters">Adding parameters to SimObjects and more events</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/memoryobject">Creating SimObjects in the memory system</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/simplecache">Creating a simple cache object</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#part3" role="button" aria-expanded="false" aria-controls="collapseExample">
        Modeling Cache Coherence with Ruby
      </a>
      <div class="collapse " id="part3">
        
          <a class="subitem " href="/documentation/learning_gem5/part3/MSIintro">Introduction to Ruby</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-intro">MSI example cache protocol</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-declarations">Declaring a state machine</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-in-ports">In port code blocks</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-actions">Action code blocks</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-transitions">Transition code blocks</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/directory">MSI Directory implementation</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/MSIbuilding">Compiling a SLICC protocol</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/configuration">Configuring a simple Ruby system</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/running">Running the simple Ruby system</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/MSIdebugging">Debugging SLICC Protocols</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/simple-MI_example">Configuring for a standard protocol</a>
        
      </div>
    
      <a class="item" href="/documentation/learning_gem5/gem5_101/" role="button" aria-expanded="false" aria-controls="collapseExample">
        gem5 101
      </a>
      <div class="collapse " id="gem5_101">
        
      </div>
    
    
  
    
  
    
  
</div>


<div class="container" id="doc-container">
  <div class="edit"><a href="https://gem5.googlesource.com/public/gem5-website/+/refs/heads/master/README.md">Edit this page</a></div>
  <b>authors:</b> Jason Lowe-Power<br>
  

  <br>
  <h1 id="creating-a-simple-configuration-script">Creating a simple configuration script</h1>

<p>This chapter of the tutorial will walk you through how to set up a
simple simulation script for gem5 and to run gem5 for the first time.
It’s assumed that you’ve completed the first chapter of the tutorial and
have successfully built gem5 with an executable <code class="highlighter-rouge">build/X86/gem5.opt</code>.</p>

<p>Our configuration script is going to model a very simple system. We’ll
have just one simple CPU core. This CPU core will be connected to a
system-wide memory bus. And we’ll have a single DDR3 memory channel,
also connected to the memory bus.</p>

<h2 id="gem5-configuration-scripts">gem5 configuration scripts</h2>

<p>The gem5 binary takes, as a parameter, a python script which sets up and
executes the simulation. In this script, you create a system to
simulate, create all of the components of the system, and specify all of
the parameters for the system components. Then, from the script, you can
begin the simulation.</p>

<p>This script is completely user-defined. You can choose to use any valid
Python code in the configuration scripts. This book provides on example
of a style that relies heavily classes and inheritance in Python. As a
gem5 user, it’s up to you how simple or complicated to make your
configuration scripts.</p>

<p>There are a number of example configuration scripts that ship with gem5
in <code class="highlighter-rouge">configs/examples</code>. Most of these scripts are all-encompassing and
allow users to specify almost all options on the command line. Instead
of starting with these complex script, in this book we are going to
start with the most simple script that can run gem5 and build from
there. Hopefully, by the end of this section you’ll have a good idea of
how simulation scripts work.</p>

<blockquote>
  <p><strong>An aside on SimObjects</strong></p>

  <p>gem5’s modular design is built around the <strong>SimObject</strong> type. Most of
the components in the simulated system are SimObjects: CPUs, caches,
memory controllers, buses, etc. gem5 exports all of these objects from
their <code class="highlighter-rouge">C++</code> implementation to python. Thus, from the python
configuration script you can create any SimObject, set its parameters,
and specify the interactions between SimObjects.</p>

  <p>See <a href="http://www.gem5.org/SimObjects">http://www.gem5.org/SimObjects</a> for more information.</p>
</blockquote>

<h2 id="creating-a-config-file">Creating a config file</h2>

<p>Let’s start by creating a new config file and opening it:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir configs/tutorial
touch configs/tutorial/simple.py
</code></pre></div></div>

<p>This is just a normal python file that will be executed by the embedded
python in the gem5 executable. Therefore, you can use any features and
libraries available in python.</p>

<p>The first thing we’ll do in this file is import the m5 library and all
SimObjects that we’ve compiled.</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import m5
from m5.objects import *
</code></pre></div></div>

<p>Next, we’ll create the first SimObject: the system that we are going to
simulate. The <code class="highlighter-rouge">System</code> object will be the parent of all the other
objects in our simulated system. The <code class="highlighter-rouge">System</code> object contains a lot of
functional (not timing-level) information, like the physical memory
ranges, the root clock domain, the root voltage domain, the kernel (in
full-system simulation), etc. To create the system SimObject, we simply
instantiate it like a normal python class:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>system = System()
</code></pre></div></div>

<p>Now that we have a reference to the system we are going to simulate,
let’s set the clock on the system. We first have to create a clock
domain. Then we can set the clock frequency on that domain. Setting
parameters on a SimObject is exactly the same as setting members of an
object in python, so we can simply set the clock to 1 GHz, for instance.
Finally, we have to specify a voltage domain for this clock domain.
Since we don’t care about system power right now, we’ll just use the
default options for the voltage domain.</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>system.clk_domain = SrcClockDomain()
system.clk_domain.clock = '1GHz'
system.clk_domain.voltage_domain = VoltageDomain()
</code></pre></div></div>

<p>Once we have a system, let’s set up how the memory will be simulated. We
are going to use <em>timing</em> mode for the memory simulation. You will
almost always use timing mode for the memory simulation, except in
special cases like fast-forwarding and restoring from a checkpoint. We
will also set up a single memory range of size 512 MB, a very small
system. Note that in the python configuration scripts, whenever a size
is required you can specify that size in common vernacular and units
like <code class="highlighter-rouge">'512MB'</code>. Similarly, with time you can use time units (e.g.,
<code class="highlighter-rouge">'5ns'</code>). These will automatically be converted to a common
representation, respectively.</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>system.mem_mode = 'timing'
system.mem_ranges = [AddrRange('512MB')]
</code></pre></div></div>

<p>Now, we can create a CPU. We’ll start with the most simple timing-based
CPU in gem5, <em>TimingSimpleCPU</em>. This CPU model executes each instruction
in a single clock cycle to execute, except memory requests, which flow
through the memory system. To create the CPU you can simply just
instantiate the object:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>system.cpu = TimingSimpleCPU()
</code></pre></div></div>

<p>Next, we’re going to create the system-wide memory bus:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>system.membus = SystemXBar()
</code></pre></div></div>

<p>Now that we have a memory bus, let’s connect the cache ports on the CPU
to it. In this case, since the system we want to simulate doesn’t have
any caches, we will connect the I-cache and D-cache ports directly to
the membus. In this example system, we have no caches.</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>system.cpu.icache_port = system.membus.slave
system.cpu.dcache_port = system.membus.slave
</code></pre></div></div>

<blockquote>
  <p><strong>An aside on gem5 ports</strong></p>

  <p>To connect memory system components together, gem5 uses a port
abstraction. Each memory object can have two kinds of ports, <em>master
ports</em> and <em>slave ports</em>. Requests are sent from a master port to a
slave port, and responses are sent from a slave port to a master port.
When connecting ports, you must connect a master port to a slave port.</p>

  <p>Connecting ports together is easy to do from the python configuration
files. You can simply set the master port <code class="highlighter-rouge">=</code> to the slave port and
they will be connected. For instance:</p>

  <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>memobject1.master = memobject2.slave
</code></pre></div>  </div>

  <p>The master and slave can be on either side of the <code class="highlighter-rouge">=</code> and the same
connection will be made. After making the connection, the master can
send requests to the slave port. There is a lot of magic going on
behind the scenes to set up the connection, the details of which are
unimportant for most users.</p>

  <p>We will discuss ports and MemObject in more detail in
memoryobject-chapter.</p>
</blockquote>

<p>Next, we need to connect up a few other ports to make sure that our
system will function correctly. We need to create an I/O controller on
the CPU and connect it to the memory bus. Also, we need to connect a
special port in the system up to the membus. This port is a
functional-only port to allow the system to read and write memory.</p>

<p>Connecting the PIO and interrupt ports to the memory bus is an
x86-specific requirement. Other ISAs (e.g., ARM) do not require these 3
extra lines.</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>system.cpu.createInterruptController()
system.cpu.interrupts[0].pio = system.membus.master
system.cpu.interrupts[0].int_master = system.membus.slave
system.cpu.interrupts[0].int_slave = system.membus.master

system.system_port = system.membus.slave
</code></pre></div></div>

<p>Next, we need to create a memory controller and connect it to the
membus. For this system, we’ll use a simple DDR3 controller and it will
be responsible for the entire memory range of our system.</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>system.mem_ctrl = DDR3_1600_8x8()
system.mem_ctrl.range = system.mem_ranges[0]
system.mem_ctrl.port = system.membus.master
</code></pre></div></div>

<p>After those final connections, we’ve finished instantiating our
simulated system! Our system should look like simple-config-fig.</p>

<p><img src="/pages/static/figures/simple_config.png" alt="A simple system configuration without
caches." /></p>

<p>Next, we need to set up the process we want the CPU to execute. Since we
are executing in syscall emulation mode (SE mode), we will just point
the CPU at the compiled executable. We’ll execute a simple “Hello world”
program. There’s already one that is compiled that ships with gem5, so
we’ll use that. You can specify any application built for x86 and that’s
been statically compiled.</p>

<blockquote>
  <p><strong>Full system vs syscall emulation</strong></p>

  <p>gem5 can run in two different modes called “syscall emulation” and
“full system” or SE and FS modes. In full system mode (covered later
full-system-part), gem5 emulates the entire hardware system and runs
an unmodified kernel. Full system mode is similar to running a virtual
machine.</p>

  <p>Syscall emulation mode, on the other hand, does not emulate all of the
devices in a system and focuses on simulating the CPU and memory
system. Syscall emulation is much easier to configure since you are
not required to instantiate all of the hardware devices required in a
real system. However, syscall emulation only emulates Linux system
calls, and thus only models user-mode code.</p>

  <p>If you do not need to model the operating system for your research
questions, and you want extra performance, you should use SE mode.
However, if you need high fidelity modeling of the system, or OS
interaction like page table walks are important, then you should use
FS mode.</p>
</blockquote>

<p>First, we have to create the process (another SimObject). Then we set
the processes command to the command we want to run. This is a list
similar to argv, with the executable in the first position and the
arguments to the executable in the rest of the list. Then we set the CPU
to use the process as it’s workload, and finally create the functional
execution contexts in the CPU.</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>process = Process()
process.cmd = ['tests/test-progs/hello/bin/x86/linux/hello']
system.cpu.workload = process
system.cpu.createThreads()
</code></pre></div></div>

<p>The final thing we need to do is instantiate the system and begin
execution. First, we create the <code class="highlighter-rouge">Root</code> object. Then we instantiate the
simulation. The instantiation process goes through all of the SimObjects
we’ve created in python and creates the <code class="highlighter-rouge">C++</code> equivalents.</p>

<p>As a note, you don’t have to instantiate the python class then specify
the parameters explicitly as member variables. You can also pass the
parameters as named arguments, like the <code class="highlighter-rouge">Root</code> object below.</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root = Root(full_system = False, system = system)
m5.instantiate()
</code></pre></div></div>

<p>Finally, we can kick off the actual simulation! As a side now, gem5 is
now using Python 3-style <code class="highlighter-rouge">print</code> functions, so <code class="highlighter-rouge">print</code> is no longer a
statement and must be called as a function.</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>print("Beginning simulation!")
exit_event = m5.simulate()
</code></pre></div></div>

<p>And once simulation finishes, we can inspect the state of the system.</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>print('Exiting @ tick {} because {}'
      .format(m5.curTick(), exit_event.getCause()))
</code></pre></div></div>

<h2 id="running-gem5">Running gem5</h2>

<p>Now that we’ve created a simple simulation script (the full version of
which can be found at gem5/configs/learning_gem5/part1/simple.py) we’re
ready to run gem5. gem5 can take many parameters, but requires just one
positional argument, the simulation script. So, we can simply run gem5
from the root gem5 directory as:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>build/X86/gem5.opt configs/tutorial/simple.py
</code></pre></div></div>

<p>The output should be:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem5 Simulator System.  http://gem5.org
gem5 is copyrighted software; use the --copyright option for details.

gem5 compiled Mar 16 2018 10:24:24
gem5 started Mar 16 2018 15:53:27
gem5 executing on amarillo, pid 41697
command line: build/X86/gem5.opt configs/tutorial/simple.py

Global frequency set at 1000000000000 ticks per second
warn: DRAM device capacity (8192 Mbytes) does not match the address range assigned (512 Mbytes)
0: system.remote_gdb: listening for remote gdb on port 7000
Beginning simulation!
info: Entering event queue @ 0.  Starting simulation...
Hello world!
Exiting @ tick 507841000 because exiting with last active thread context
</code></pre></div></div>

<p>Parameters in the configuration file can be changed and the results
should be different. For instance, if you double the system clock, the
simulation should finish faster. Or, if you change the DDR controller to
DDR4, the performance should be better.</p>

<p>Additionally, you can change the CPU model to <code class="highlighter-rouge">MinorCPU</code> to model an
in-order CPU, or <code class="highlighter-rouge">DerivO3CPU</code> to model an out-of-order CPU. However,
note that <code class="highlighter-rouge">DerivO3CPU</code> currently does not work with simple.py, because
<code class="highlighter-rouge">DerivO3CPU</code> requires a system with separate instruction and data caches
(<code class="highlighter-rouge">DerivO3CPU</code> does work with the configuration in the next section).</p>

<p>Next, we will add caches to our configuration file to model a more
complex system.</p>

  <br>

  <!-- RETRIVE PREVIOUS PAGE LINK -->
  
    
  
    
  
    
  
    
  

  <!-- RETRIEVE NEXT PAGE LINK -->
  
    
  
    
  
    
  
    
  


  <div class="navbuttons">
    
      <a href=""><button type="button" class="btn btn-outline-primary">PREVIOUS</button></a>
    

    
      <a href=""><button type="button" class="btn btn-outline-primary">NEXT</button></a>
    
  </div>
</div>

	</main>
	<footer class="page-footer">
	<div class="container">
		<div class="row">

			<div class="col-12 col-sm-4">
				<p>gem5</p>
				<p><a href="/about">About</a></p>
				<p><a href="/publications">Publications</a></p>
				<p><a href="/contributing">Contributing</a></p>
				<p><a href="/governance">Governance</a></p>
			<br></div>

			<div class="col-12 col-sm-4">
				<p>Docs</p>
				<p><a href="/documentation">Documentation</a></p>
				<p><a href="http://gem5.org/Documentation">Old Documentation</a></p>
				<p><a href="https://gem5.googlesource.com/public/gem5">Source</a></p>
			<br></div>

			<div class="col-12 col-sm-4">
				<p>Help</p>
				<p><a href="/search">Search</a></p>
				<p><a href="/mailing_lists">Mailing Lists</a></p>
				<p><a href="https://gem5.googlesource.com/public/gem5-website/+/refs/heads/master/README.md">Website Source</a></p>
			<br></div>

		</div>
	</div>
</footer>


	<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
	<script src="https://unpkg.com/commentbox.io/dist/commentBox.min.js"></script>

	<script>
	  // When the user scrolls down 20px from the top of the document, show the button
	  window.onscroll = function() {scrollFunction()};

	  function scrollFunction() {
	      if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 20) {
	          document.getElementById("myBtn").style.display = "block";
	      } else {
	          document.getElementById("myBtn").style.display = "none";
	      }
	  }

	  // When the user clicks on the button, scroll to the top of the document
	  function topFunction() {
	      document.body.scrollTop = 0;
	      document.documentElement.scrollTop = 0;
	  }

		import commentBox from 'commentbox.io';
		// or
		const commentBox = require('commentbox.io');
		// or if using the CDN, it will be available as a global "commentBox" variable.

		commentBox('my-project-id');

	</script>

</body>


</html>
